/*******************************************************************************
 * Copyright (c) 2009-2011 ETCORE Labs. All rights reserved. 
 * 
 * This software is the confidential and proprietary information of ETCORE Labs.
 * You shall not disclose such confidential information and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with ETCORE Labs. 
 * 
 * Support can be obtained from support forums at:  http://www.etcore.com/
 * /
 *******************************************************************************/
package etcore.webapp.grouptalk.util;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;

/**
 * SymmetricEncryptionUtil is a utility class with operations of symmetric
 * encryption
 * 
 * 
 * @author ETCORE GroupTalk Developers
 * 
 */
public class SymmetricEncryptionUtil {
	public static final String DESAlgorithm = "DES";

	public static final String DES3Algorithm = "DESede";

	public static final String BlowfishAlgorithm = "Blowfish";

	public static final String AESAlgorithm = "AES";

	public static final String KEY = "aabbccdd11223344";

	
	public static String byte2hex(byte[] b) {
		String hs = Symbols.BLANK;
		String stmp = Symbols.BLANK;
		for (int i = 0; i < b.length; i++) {
			stmp = Integer.toHexString(b[i] & 0xFF);
			if (stmp.length() == 1) {
				hs += "0" + stmp;
			} else {
				hs += stmp;
			}
		}
		return hs.toUpperCase();
	}

	public static byte[] decryptMode(byte[] keybyte, byte[] src,
			String Algorithm) {
		try {

			SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);

			Cipher c1 = Cipher.getInstance(Algorithm);

			c1.init(Cipher.DECRYPT_MODE, deskey);
			return c1.doFinal(src);
		} catch (java.security.NoSuchAlgorithmException e1) {
			e1.printStackTrace();

		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}

	public static byte[] encryptMode(byte[] keybyte, byte[] src,
			String Algorithm) {
		try {

			SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);

			Cipher c1 = Cipher.getInstance(Algorithm);
			c1.init(Cipher.ENCRYPT_MODE, deskey);
			return c1.doFinal(src);
		} catch (java.security.NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}

	public static String getDecryptedStr(String input) {
		return getDecryptedStr(input, BlowfishAlgorithm, KEY);
	}

	public static String getDecryptedStr(String input, String algorithm,
			String key) {
		if (input == null || key == null || algorithm == null)
			return null;
		byte[] keyBytes = SymmetricEncryptionUtil
				.setBlowfishKey(key.getBytes());
		byte[] src = hex2byte(input);
		byte[] result = decryptMode(keyBytes, src, algorithm);
		return new String(result);
	}

	public static String getEncryptedStr(String input) {
		return getEncryptedStr(input, BlowfishAlgorithm, KEY);
	}

	public static String getEncryptedStr(String input, String algorithm,
			String key) {
		if (input == null || key == null || algorithm == null)
			return null;
		byte[] keyBytes = SymmetricEncryptionUtil
				.setBlowfishKey(key.getBytes());
		byte[] src = input.getBytes();
		byte[] result = encryptMode(keyBytes, src, algorithm);
		return byte2hex(result);

	}

	public static byte[] hex2byte(String hex) throws IllegalArgumentException {
		if (hex.length() % 2 != 0) {
			throw new IllegalArgumentException();
		}
		char[] arr = hex.toCharArray();
		byte[] b = new byte[hex.length() / 2];
		for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) {
			String swap = Symbols.BLANK + arr[i++] + arr[i];
			int byteint = Integer.parseInt(swap, 16) & 0xFF;
			b[j] = new Integer(byteint).byteValue();
		}
		return b;
	}

	public static byte[] setAESKey(byte[] keyBytes) {
		return setKey(keyBytes, 16);

	}

	public static byte[] setBlowfishKey(byte[] keyBytes) {
		return setKey(keyBytes, 16);

	}

	public static byte[] setDES3Key(byte[] keyBytes) {
		return setKey(keyBytes, 24);

	}

	public static byte[] setDESKey(byte[] keyBytes) {

		return setKey(keyBytes, 8);

	}

	public static byte[] setKey(byte[] keyBytes, int keySize) {
		if (keyBytes == null || keySize < 1)
			return null;
		if (keyBytes.length <= keySize)
			return keyBytes;
		byte[] result = new byte[keySize];

		if (keyBytes.length > keySize) {
			System.arraycopy(keyBytes, 0, result, 0, keySize);
		}
		return result;

	}

}
